package com.example.user1.infra;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.user1.domain.UserRepository;
import com.example.user1.domain.convert.UserConvert;
import com.example.user1.infra.mapper.UserMapper;
import com.example.user1.infra.mapper.entity.UserEntity;
import com.example.user1.infra.model.UserModel;
import com.example.user1.util.IdUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class UserRepositoryImpl extends ServiceImpl<UserMapper,UserEntity> implements UserRepository {
    private final UserMapper userMapper;
    private final UserConvert userConvert;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(UserModel model) {
        model.setId(IdUtils.nextId());
        UserEntity entity = userConvert.toEntity(model);
        entity.setPassword(bCryptPasswordEncoder.encode(entity.getPassword()));
        return userMapper.insert(entity);
    }

    @Override
    public UserModel get(Long id) {
        return userConvert.toDomain(userMapper.selectById(id));
    }

    @Override
    public UserModel getByUsername(String username) {
        UserEntity userEntity = userMapper.selectOne(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getUsername, username));
        return userConvert.toDomain(userEntity);
    }

    @Override
    public boolean existByUsername(String username) {
        return userMapper.selectCount(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getUsername, username)) > 0;
    }

    @Override
    public boolean existByUsernameLock(String username) {
        return userMapper.selectCount(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getUsername, username).last("for update")) > 0;
    }

    @Override
    public boolean existByPhone(String phone) {
        return userMapper.selectCount(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getPhoneNumber, phone)) > 0;
    }

    @Override
    public boolean existByPhoneLock(String phone) {
        return userMapper.selectCount(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getPhoneNumber, phone).last("for update")) > 0;
    }
}
